﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace RiskMan.DataClass.Gerchik
{
    [Serializable]
    public class GechikRobotItem : INotifyPropertyChanged, ISerializable
    {
        #region private

        private bool _checked;
        private bool _isRun;
        //Базовые настройки
        private string _account;
        private string _clientCode;
        private string _market;
        private string _instrument;
        private int _quantity;
        private string _timeFrame;
        private Guid _guidLevelItem;
        private ObservableCollection<TradesOpen> _tradeList;
        //рабочие настройки роботазк
        
        private double _thirdBarDeviation;
        private double _killOrderPoint;
        private double _stopLimiOtstup;
        private double _profit;
        private double _breakeven;
        private double _maxExcess;
        private double _levelPrice;
        private bool _requestData;
        private int _attemptAmount;
        private int _currentAttempt;
        private bool _addCurrentAttempt;
        //private double _deviationKillOrder;
        private DateTime _timeStartLevel;
        private DateTime _timeStopLevel;
        private DateTime _timeClosePoz;
        private bool _reapetEnterOnLevel;
        private List<double> _listLevel;


        //Доболнительные настройки
        private string _typeRobot;
        private bool _soundAlert;
        //Паттерны
        private List<string> _patterns;

        //информация из терминала
        private double _lastPrice;
        private double _prevCurOpen;
        private int _curPosition;
        private TimeSpan _prevTime;
        private DateTime _lastDateTimeCandel;

        //внутренние переменные
        private bool _closeEndDay;
        private bool _breakevenFlag;
        private DateTime _timeAttemptOpenPoz;
        private bool _commentForFirstCandle;

       
        //private ObservableCollection<PatternItem> _patterns;

        #endregion

        #region public

        #region Patterns
        
        /// <summary>
        /// Паттерны по которым идет торговля
        /// </summary>
        public List<string> Patterns
        {
            get { return _patterns; }
            set
            {
                if (_patterns != value)
                {
                    _patterns = value;
                    RaisePropertyChanged("Patterns");
                }
            }
        }
           

        #endregion

        #region внутренние переменные

        
        /// <summary>
        /// Время последней обработанной свечи для логики робота
        /// </summary>
        public DateTime LastDateTimeCandel
        {
            get { return _lastDateTimeCandel; }
            set
            {
                if (_lastDateTimeCandel != value)
                {
                    _lastDateTimeCandel = value;
                    RaisePropertyChanged("LastDateTimeCandel");
                }
            }
        }
           
        /// <summary>
        /// Показывает, была ли попытка засчитана или нет, считаются только попытки входа в позицию
        /// </summary>
        public bool AddCurrentAttempt
        {
            get { return _addCurrentAttempt; }
            set
            {
                if (_addCurrentAttempt != value)
                {
                    _addCurrentAttempt = value;
                    RaisePropertyChanged("AddCurrentAttempt");
                }
            }
        }
           
        /// <summary>
        /// текущее количество попыток для входа после выхода по стопу или безубытку
        /// </summary>
        public int CurrentAttempt
        {
            get { return _currentAttempt; }
            set
            {
                if (_currentAttempt != value)
                {
                    _currentAttempt = value;
                    RaisePropertyChanged("CurrentAttempt");
                }
            }
        }

        /// <summary>
        /// количество попыток для входа после выхода по стопу или безубытку
        /// </summary>
        public int AttemptAmount
        {
            get { return _attemptAmount; }
            set
            {
                if (_attemptAmount != value)
                {
                    _attemptAmount = value;
                    RaisePropertyChanged("AttemptAmount");
                }
            }
        }

        /// <summary>
        /// Локальная переменная для фильтра перенос стоп в безубыток
        /// </summary>
        public bool BreakevenFlag
        {
            get { return _breakevenFlag; }
            set
            {
                if (_breakevenFlag != value)
                {
                    _breakevenFlag = value;
                    RaisePropertyChanged("BreakevenFlag");
                }
            }
        }

        /// <summary>
        /// Локальная переменная для фильтра отправки одной заявки на закрытие позиции в конце дня
        /// </summary>
        public bool CloseEndDay
        {
            get { return _closeEndDay; }
            set
            {
                if (_closeEndDay != value)
                {
                    _closeEndDay = value;
                    RaisePropertyChanged("CloseEndDay");
                }
            }
        }

        #endregion

        #region Базовые настройки



        /// <summary>
        /// Время предыдущей свечи
        /// </summary>
        public TimeSpan PrevTime
        {
            get { return _prevTime; }
            set
            {
                if (_prevTime != value)
                {
                    _prevTime = value;
                    RaisePropertyChanged("PrevTime");
                }
            }
        }

        /// <summary>
        /// выделен элемент для выполенения операции или нет
        /// </summary>
        public bool Check
        {
            get { return _checked; }
            set
            {
                if (_checked != value)
                {
                    _checked = value;
                    RaisePropertyChanged("Check");
                }
            }
        }

        /// <summary>
        /// Торговый счет
        /// </summary>
        public string Account
        {
            get { return _account; }
            set
            {
                if (_account != value)
                {
                    _account = value;
                    RaisePropertyChanged("Account");
                }
            }
        }

        /// <summary>
        /// Счет депо
        /// </summary>
        public string ClientCode
        {
            get { return _clientCode; }
            set
            {
                if (_clientCode != value)
                {
                    _clientCode = value;
                    RaisePropertyChanged("ClientCode");
                }
            }
        }

        /// <summary>
        /// рынок для торговли
        /// </summary>
        public string Market
        {
            get { return _market; }
            set
            {
                if (_market != value)
                {
                    _market = value;
                    RaisePropertyChanged("Market");
                }
            }
        }

        /// <summary>
        /// таймфрейм
        /// </summary>
        public string TimeFrame
        {
            get { return _timeFrame; }
            set
            {
                if (_timeFrame != value)
                {
                    _timeFrame = value;
                    RaisePropertyChanged("TimeFrame");
                }
            }
        }

        /// <summary>
        /// Торгуемый инструмент
        /// </summary>
        public string Instrument
        {
            get { return _instrument; }
            set
            {
                if (_instrument != value)
                {
                    _instrument = value;
                    RaisePropertyChanged("Instrument");
                }
            }
        }


        /// <summary>
        /// Количество лотов
        /// </summary>
        public int Quantity
        {
            get { return _quantity; }
            set
            {
                if (_quantity != value)
                {
                    _quantity = value;
                    RaisePropertyChanged("Quantity");
                }
            }
        }

        /// <summary>
        /// Запуск/остановка работы по данному инструменту
        /// </summary>
        public bool IsRun
        {
            get { return _isRun; }
            set
            {
                if (_isRun != value)
                {
                    _isRun = value;
                    RaisePropertyChanged("IsRun");
                }
            }
        }

        /// <summary>
        /// коллекция активнных и исполненных сделок на открытие и закрытие позиции
        /// </summary>
        public ObservableCollection<TradesOpen> TradeList
        {
            get { return _tradeList; }
            set
            {
                if (_tradeList != value)
                {
                    _tradeList = value;
                    RaisePropertyChanged("TradeList");
                }
            }
        }

        /// <summary>
        /// уникальный номер уровня, чтоб не терялся при сортировке
        /// </summary>
        public Guid GuidLevelItem
        {
            get { return _guidLevelItem; }
            set
            {
                if (_guidLevelItem != value)
                {
                    _guidLevelItem = value;
                    RaisePropertyChanged("GuidLevelItem");
                }
            }
        }
        #endregion


        #region Настройки робота
        

        /// <summary>
        /// Показывает, нужно ли запрашивать историю данные
        /// </summary>
        public bool RequestData
        {
            get { return _requestData; }
            set
            {
                if (_requestData != value)
                {
                    _requestData = value;
                    RaisePropertyChanged("RequestData");
                }
            }
        }

        /// <summary>
        /// Уровень робота
        /// </summary>
        public double LevelPrice
        {
            get { return _levelPrice; }
            set
            {
                if (_levelPrice != value)
                {
                    _levelPrice = value;
                    RaisePropertyChanged("LevelPrice");
                }
            }
        }

        /// <summary>
        /// Отклонение третей свечи от уровня не более чем на заданное количество
        /// </summary>
        public double ThirdBarDeviation
        {
            get { return _thirdBarDeviation; }
            set
            {
                if (_thirdBarDeviation != value)
                {
                    _thirdBarDeviation = value;
                    RaisePropertyChanged("ThirdBarDeviation");
                }
            }
        }

        /// <summary>
        /// Снятие заявки при уходе цены инструмента, от цены выставления заявки на заднное количество пукнтов
        /// </summary>
        public double KillOrderPoint
        {
            get { return _killOrderPoint; }
            set
            {
                if (_killOrderPoint != value)
                {
                    _killOrderPoint = value;
                    RaisePropertyChanged("KillOrderPoint");
                }
            }
        }

        /// <summary>
        /// Отступ для стоп заявки от уровня
        /// </summary>
        public double StopLimiOtstup
        {
            get { return _stopLimiOtstup; }
            set
            {
                if (_stopLimiOtstup != value)
                {
                    _stopLimiOtstup = value;
                    RaisePropertyChanged("StopLimiOtstup");
                }
            }
        }

        /// <summary>
        /// Запланированная величина прибыли
        /// </summary>
        public double Profit
        {
            get { return _profit; }
            set
            {
                if (_profit != value)
                {
                    _profit = value;
                    RaisePropertyChanged("Profit");
                }
            }
        }

        /// <summary>
        /// Перенос стоп в безубыток, как только отклонение цены от уровня будет равно или выше заданной величины
        /// </summary>
        public double Breakeven
        {
            get { return _breakeven; }
            set
            {
                if (_breakeven != value)
                {
                    _breakeven = value;
                    RaisePropertyChanged("Breakeven");
                }
            }
        }

        /// <summary>
        /// Максимальное превышение при открытие четвертой свечи от уровня, если превышение заданного значенияя, то выставляем лимитную заявку уровень +/- MaxExcess
        /// </summary>
        public double MaxExcess
        {
            get { return _maxExcess; }
            set
            {
                if (_maxExcess != value)
                {
                    _maxExcess = value;
                    RaisePropertyChanged("MaxExcess");
                }
            }
        }

        ///// <summary>
        ///// снятие отсавшейся заявки, если цена ушла на заданное количество пунктов
        ///// </summary>
        //public double DeviationKillOrder
        //{
        //    get { return _deviationKillOrder; }
        //    set
        //    {
        //        if (_deviationKillOrder != value)
        //        {
        //            _deviationKillOrder = value;
        //            RaisePropertyChanged("DeviationKillOrder");
        //        }
        //    }
        //}

        /// <summary>
        /// Время начала формирования уровня
        /// </summary>
        public DateTime TimeStartLevel
        {
            get { return _timeStartLevel; }
            set
            {
                if (_timeStartLevel != value)
                {
                    _timeStartLevel = value;
                    RaisePropertyChanged("TimeStartLevel");
                }
            }
        }

        /// <summary>
        /// Время окончания формирования уровня
        /// </summary>
        public DateTime TimeStopLevel
        {
            get { return _timeStopLevel; }
            set
            {
                if (_timeStopLevel != value)
                {
                    _timeStopLevel = value;
                    RaisePropertyChanged("TimeStopLevel");
                }
            }
        }

        /// <summary>
        /// Время закрытия позиций в конце дня
        /// </summary>
        public DateTime TimeClosePoz
        {
            get { return _timeClosePoz; }
            set
            {
                if (_timeClosePoz != value)
                {
                    _timeClosePoz = value;
                    RaisePropertyChanged("TimeClosePoz");
                }
            }
        }

        /// <summary>
        /// Вход по отработанному уровню сегодня
        /// </summary>
        public bool ReapetEnterOnLevel
        {
            get { return _reapetEnterOnLevel; }
            set
            {
                if (_reapetEnterOnLevel != value)
                {
                    _reapetEnterOnLevel = value;
                    RaisePropertyChanged("ReapetEnterOnLevel");
                }
            }
        }


        /// <summary>
        /// Уровни отработанные сегодя
        /// </summary>
        public List<double> ListLevel
        {
            get { return _listLevel; }
            set
            {
                if (_listLevel != value)
                {
                    _listLevel = value;
                    RaisePropertyChanged("ListLevel");
                }
            }
        }

        #endregion

        #region Доболнительные настройки

        /// <summary>
        /// Тип робота: советник или боевой режим
        /// </summary>
        public string TypeRobot
        {
            get { return _typeRobot; }
            set
            {
                if (_typeRobot != value)
                {
                    _typeRobot = value;
                    RaisePropertyChanged("TypeRobot");
                }
            }
        }
        /// <summary>
        /// Включен ли звуковой сигнал на вход или выход из позиции
        /// </summary>
        public bool SoundAlert
        {
            get { return _soundAlert; }
            set
            {
                if (_soundAlert != value)
                {
                    _soundAlert = value;
                    RaisePropertyChanged("SoundAlert");
                }
            }
        }
        
        /// <summary>
        /// Время, где была попытка входа в позицию
        /// </summary>
        public DateTime TimeAttemptOpenPoz
        {
            get { return _timeAttemptOpenPoz; }
            set
            {
                if (_timeAttemptOpenPoz != value)
                {
                    _timeAttemptOpenPoz = value;
                    RaisePropertyChanged("TimeAttemptOpenPoz");
                }
            }
        }

        #endregion

        #region Информация из терминалов
        /// <summary>
        /// цена последней сделки
        /// </summary>
        public double LastPrice
        {
            get { return _lastPrice; }
            set
            {
                if (_lastPrice != value)
                {
                    _lastPrice = value;
                    RaisePropertyChanged("LastPrice");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public double PrevCurOpen
        {
            get { return _prevCurOpen; }
            set
            {
                if (_prevCurOpen != value)
                {
                    _prevCurOpen = value;
                    RaisePropertyChanged("PrevCurOpen");
                }
            }
        }

        /// <summary>
        /// цена последней сделки
        /// </summary>
        public int CurPosition
        {
            get { return _curPosition; }
            set
            {
                if (_curPosition != value)
                {
                    _curPosition = value;
                    RaisePropertyChanged("CurPosition");
                }
            }
        }

        /// <summary>
        /// Информация для лога о первой свече
        /// </summary>
        public bool CommentForFirstCandle
        {
            get { return _commentForFirstCandle; }
            set
            {
                if (_commentForFirstCandle != value)
                {
                    _commentForFirstCandle = value;
                    RaisePropertyChanged("CommentForFirstCandle");
                }
            }
        }
           

        #endregion
        #endregion


        public GechikRobotItem() { }

        #region event PropertyChangedEventHandler

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        public GechikRobotItem(SerializationInfo info, StreamingContext context)
        {
            IsRun = info.GetBoolean("IsRun");
            Check = info.GetBoolean("Check");
            Account = info.GetString("Account");
            //ClientCode = info.GetString("ClientCode");
            //Market = info.GetString("Market");
            //Instrument = info.GetString("Instrument");
            //Quantity = info.GetInt32("Quantity");
            //TradeList = (ObservableCollection<TradesOpen>)info.GetValue("TradeList", typeof(ObservableCollection<TradesOpen>));
            //GuidLevelItem = (Guid)info.GetValue("GuidLevelItem", typeof(Guid));

            //ThirdBarDeviation = info.GetDouble("ThirdBarDeviation");
            //KillOrderPoint = info.GetDouble("KillOrderPoint");
            //StopLimiOtstup = info.GetDouble("StopLimiOtstup");
            //Profit = info.GetDouble("Profit");
            //Breakeven = info.GetDouble("Breakeven");
            //MaxExcess = info.GetDouble("MaxExcess");
            ////DeviationKillOrder = info.GetDouble("DeviationKillOrder");
            //TimeStartLevel = info.GetDateTime("TimeStartLevel");
            //TimeStopLevel = info.GetDateTime("TimeStopLevel");
            //TimeClosePoz = info.GetDateTime("TimeClosePoz");
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("isRun", IsRun);
            info.AddValue("Check", Check);
            info.AddValue("Account", Account);
            //info.AddValue("ClientCode", ClientCode);
            //info.AddValue("Market", Market);
            //info.AddValue("Instrument", Instrument);
            //info.AddValue("Quantity", Quantity);
            //info.AddValue("GuidLevelItem", GuidLevelItem);
            //info.AddValue("TradeList", TradeList);

            //info.AddValue("ThirdBarDeviation", ThirdBarDeviation);
            //info.AddValue("KillOrderPoint", KillOrderPoint);
            //info.AddValue("StopLimiOtstup", StopLimiOtstup);
            //info.AddValue("Profit", Profit);
            //info.AddValue("Breakeven", Breakeven);
            //info.AddValue("MaxExcess", MaxExcess);
            ////info.AddValue("DeviationKillOrder", DeviationKillOrder);
            //info.AddValue("TimeStartLevel", TimeStartLevel);
            //info.AddValue("TimeStopLevel", TimeStopLevel);
            //info.AddValue("TimeClosePoz", TimeClosePoz);
        }
    }
}
